#!/usr/bin/env python
# coding: utf-8

# In[4]:


import datetime
import requests

class EtigerBacktestClient:
    def __init__(self, base_url, username, password):
        self.__base_url = base_url
        self.__oauth_token_url = self.__base_url + '/oauth/token'
        self.__username = username
        self.__password = password
        self.__oauth_token = None
        self.__factor_file_url = self.__base_url + '/backtest/api/factor/file'
        self.__factor_file_upload_url = self.__base_url + '/backtest/api/factor/file/upload'
        self.__factor_task_url = self.__base_url + '/backtest/api/factor/task'
    def __parse_json_response(self, rsp):
        code = rsp['code']
        msg = rsp['msg']
        trace_id = rsp['traceId']
        if '0' == code:
            return rsp['data']
        else:
            print("[%s][ERROR] EtigerBacktestClient response error, trace_id [%s]" %(datetime.datetime.now(), trace_id))
            raise Exception(msg)
    def __get_oauth_token(self):
        payload = {
            'username': self.__username,
            'password': self.__password
        }
        rsp = requests.get(self.__oauth_token_url, params=payload, verify=True)
        rsp = rsp.json()
        rsp = self.__parse_json_response(rsp)
        self.__oauth_token = rsp['accessToken']
        return  self.__oauth_token
    def __init_oauth_token(self):
        if self.__oauth_token is None:
            self.__get_oauth_token()
        if self.__oauth_token is None:
            raise Exception("cannot get oauth token")
    def __get_url_with_token(self, url):
        return url + "?token=" + self.__oauth_token
    def get_factor_file(self):
        '''
        查询可用的因子数据文件
        '''
        self.__init_oauth_token()
        url = self.__get_url_with_token(self.__factor_file_url)
        rsp = requests.get(url, verify=True)
        rsp = rsp.json()
        return self.__parse_json_response(rsp)
    def upload_factor_file(self, filename, replace, filepath):
        '''
        上传因子数据文件
        '''
        self.__init_oauth_token()
        url = self.__get_url_with_token(self.__factor_file_upload_url)
        payload = {
            'filename': filename,
            'replace': replace
        }
        files = {
            'file': open(filepath, 'rb')
        }
        rsp = requests.post(url, params=payload, files=files, verify=True)
        rsp = rsp.json()
        return self.__parse_json_response(rsp)
    def get_factor_task(self):
        '''
        查询因子回测任务
        '''
        self.__init_oauth_token()
        url = self.__get_url_with_token(self.__factor_task_url)
        rsp = requests.get(url, verify=True)
        rsp = rsp.json()
        return self.__parse_json_response(rsp)
    def add_factor_task(self, description, factor_file_name, quantile, begin_date, end_date, max_position_ratio):
        '''
        添加因子回测任务
        '''
        self.__init_oauth_token()
        url = self.__get_url_with_token(self.__factor_task_url)
        payload = {
            'description': description,
            'factorFilename': factor_file_name,
            'quantile': quantile,
            'beginDate': begin_date,
            'endDate': end_date,
            'maxPositionRatio': max_position_ratio
        }
        rsp = requests.post(url, json=payload, verify=True)
        rsp = rsp.json()
        return self.__parse_json_response(rsp)
    def get_factor_task_by_task_id(self, task_id):
        '''
        查询因子回测任务
        '''
        self.__init_oauth_token()
        url = self.__factor_task_url + "/" + task_id
        url = self.__get_url_with_token(url)
        rsp = requests.get(url, verify=True)
        rsp = rsp.json()
        return self.__parse_json_response(rsp)
    def download_task_account_file(self, task_id, to_file):
        '''
        下载accountFile
        '''
        self.__init_oauth_token()
        url = self.__factor_task_url + "/" + task_id + "/result/account/download"
        url = self.__get_url_with_token(url)
        rsp = requests.get(url, verify=True, stream=True)
        with open(to_file, 'wb') as fd:
            for chunk in rsp.iter_content(chunk_size=4096):
                fd.write(chunk)
    def download_task_position_file(self, task_id, to_file):
        '''
        下载positionFile
        '''
        self.__init_oauth_token()
        url = self.__factor_task_url + "/" + task_id + "/result/position/download"
        url = self.__get_url_with_token(url)
        rsp = requests.get(url, verify=True, stream=True)
        with open(to_file, 'wb') as fd:
            for chunk in rsp.iter_content(chunk_size=4096):
                fd.write(chunk)
    def download_task_order_file(self, task_id, to_file):
        '''
        下载orderFile
        '''
        self.__init_oauth_token()
        url = self.__factor_task_url + "/" + task_id + "/result/order/download"
        url = self.__get_url_with_token(url)
        rsp = requests.get(url, verify=True, stream=True)
        with open(to_file, 'wb') as fd:
            for chunk in rsp.iter_content(chunk_size=4096):
                fd.write(chunk)
    def delete_factor_task_by_task_id(self, task_id):
        '''
        删除因子回测任务
        '''
        self.__init_oauth_token()
        url = self.__factor_task_url + "/" + task_id
        url = self.__get_url_with_token(url)
        rsp = requests.delete(url, verify=True)
        rsp = rsp.json()
        return self.__parse_json_response(rsp)

def example_get_factor_file(backtest_client):
    factor_file_list = backtest_client.get_factor_file()
    print("[%s][INFO] factor_file_list [%s]" %(datetime.datetime.now(), factor_file_list))

def example_upload_factor_file(backtest_client):
    upload_factor_result = backtest_client.upload_factor_file('python_upload_test', True, r'C:\Users\asd\Desktop\factor_file.csv')
    print("[%s][INFO] upload_factor_file [%s]" %(datetime.datetime.now(), upload_factor_result))

def example_get_factor_task(backtest_client):
    factor_task_list = backtest_client.get_factor_task()
    print("[%s][INFO] factor_task_list [%s]" %(datetime.datetime.now(), factor_task_list))

def example_add_factor_task(backtest_client):
    add_factor_task_result = backtest_client.add_factor_task("python_add_factor_task_test", "python_upload_test", 5, "2018-01-10", "2018-06-10", 0.8)
    print("[%s][INFO] add_factor_task [%s]" %(datetime.datetime.now(), add_factor_task_result))

def example_get_factor_task_by_task_id(backtest_client):
    factor_task = backtest_client.get_factor_task_by_task_id('9d6b86ac3e214ca7a5e89431890baadf')
    print("[%s][INFO] get_factor_task_by_task_id [%s]" %(datetime.datetime.now(), factor_task))

def example_download_task_account_file(backtest_client):
    backtest_client.download_task_account_file('9d6b86ac3e214ca7a5e89431890baadf', r'C:\Users\asd\Desktop\python_account_file.csv')
    print("[%s][INFO] download_task_account_file" %(datetime.datetime.now()))

def example_download_task_position_file(backtest_client):
    backtest_client.download_task_position_file('9d6b86ac3e214ca7a5e89431890baadf', r'C:\Users\asd\Desktop\python_position_file.csv')
    print("[%s][INFO] download_task_position_file" %(datetime.datetime.now()))

def example_download_task_order_file(backtest_client):
    backtest_client.download_task_order_file('9d6b86ac3e214ca7a5e89431890baadf', r'C:\Users\asd\Desktop\python_order_file.csv')
    print("[%s][INFO] download_task_order_file" %(datetime.datetime.now()))

def example_delete_factor_task_by_task_id(backtest_client):
    factor_task = backtest_client.delete_factor_task_by_task_id('0a50c844ddda43b89a469ccf26667e17')
    print("[%s][INFO] delete_factor_task_by_task_id [%s]" %(datetime.datetime.now(), factor_task))

if __name__ == '__main__':
    base_url = 'https://ssl.etigerfund.cn/etiger/'
    username = 'etiger'
    password = 'etigerbestone'
    backtest_client = EtigerBacktestClient(base_url, username, password)
    example_get_factor_file(backtest_client)
    example_upload_factor_file(backtest_client)
    example_get_factor_task(backtest_client)
    example_add_factor_task(backtest_client)
    example_get_factor_task_by_task_id(backtest_client)
    example_download_task_account_file(backtest_client)
    example_download_task_position_file(backtest_client)
    example_download_task_order_file(backtest_client)
    example_delete_factor_task_by_task_id(backtest_client)
